/*
* Copyright (c) 2010-2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.evolveum.midpoint.repo.sql.query2.hqm;
import com.evolveum.midpoint.repo.sql.query2.definition.JpaEntityDefinition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.AndCondition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.Condition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.InCondition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.IsNotNullCondition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.IsNullCondition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.NotCondition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.OrCondition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.PropertyPropertyComparisonCondition;
import com.evolveum.midpoint.repo.sql.query2.hqm.condition.SimpleComparisonCondition;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.Type;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author mederly
*/
public class RootHibernateQuery extends HibernateQuery {
private static final Trace LOGGER = TraceManager.getTrace(RootHibernateQuery.class);
private Map<String,QueryParameterValue> parameters = new HashMap<>();
private Integer maxResults;
private Integer firstResult;
private ResultTransformer resultTransformer;
private boolean distinct;
public RootHibernateQuery(JpaEntityDefinition primaryEntityDef) {
super(primaryEntityDef);
}
private RootHibernateQuery(EntityReference primaryEntity) {
super(primaryEntity);
}
public RootHibernateQuery createWrapperQuery() {
return new RootHibernateQuery(getPrimaryEntity());
}
public String addParameter(String prefix, Object value, Type type) {
String name = findFreeName(prefix);
parameters.put(name, new QueryParameterValue(value, type));
return name;
}
public String addParameter(String prefix, Object value) {
return addParameter(prefix, value, null);
}
public void addParametersFrom(Map<String, QueryParameterValue> newParameters) {
for (Map.Entry<String, QueryParameterValue> entry : newParameters.entrySet()) {
if (parameters.containsKey(entry.getKey())) {
throw new IllegalArgumentException("Parameter " + entry.getKey() + " already exists.");
}
parameters.put(entry.getKey(), entry.getValue());
}
}
public Map<String, QueryParameterValue> getParameters() {
return parameters;
}
private String findFreeName(String prefix) {
int i = 1;
for (;;) {
String name = i == 1 ? prefix : prefix+i;
if (!parameters.containsKey(name)) {
return name;
}
i++;
}
}
public Query getAsHqlQuery(Session session) {
String text = getAsHqlText(0, distinct);
LOGGER.trace("HQL text generated:\n{}", text);
Query query = session.createQuery(text);
for (Map.Entry<String,QueryParameterValue> parameter : parameters.entrySet()) {
String name = parameter.getKey();
QueryParameterValue parameterValue = parameter.getValue();
LOGGER.trace("Parameter {} = {}", name, parameterValue.debugDump());
if (parameterValue.getValue() instanceof Collection) {
if (parameterValue.getType() != null) {
query.setParameterList(name, (Collection) parameterValue.getValue(), parameterValue.getType());
} else {
query.setParameterList(name, (Collection) parameterValue.getValue());
}
} else {
if (parameterValue.getType() != null) {
query.setParameter(name, parameterValue.getValue(), parameterValue.getType());
} else {
query.setParameter(name, parameterValue.getValue());
}
}
}
if (maxResults != null) {
query.setMaxResults(maxResults);
}
if (firstResult != null) {
query.setFirstResult(firstResult);
}
if (resultTransformer != null) {
query.setResultTransformer(resultTransformer);
}
return query;
}
@Override
public RootHibernateQuery getRootQuery() {
return this;
}
public void setMaxResults(Integer size) {
this.maxResults = size;
}
public void setFirstResult(Integer offset) {
this.firstResult = offset;
}
public void setResultTransformer(ResultTransformer resultTransformer) {
this.resultTransformer = resultTransformer;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public Condition createIsNull(String propertyPath) {
return new IsNullCondition(this, propertyPath);
}
public Condition createIsNotNull(String propertyPath) {
return new IsNotNullCondition(this, propertyPath);
}
public Condition createEq(String propertyPath, Object value, boolean ignoreCase) {
return createSimpleComparisonCondition(propertyPath, value, "=", ignoreCase);
}
public Condition createEq(String propertyPath, Object value) {
return createEq(propertyPath, value, false);
}
public Condition createEqOrInOrNull(String propertyPath, Collection<?> values) {
if (values.isEmpty()) {
return createIsNull(propertyPath);
} else if (values.size() == 1) {
return createEq(propertyPath, values.iterator().next(), false);
} else {
return createIn(propertyPath, values);
}
}
public Condition createSimpleComparisonCondition(String propertyPath, Object value, String comparatorSymbol) {
return new SimpleComparisonCondition(this, propertyPath, value, comparatorSymbol, false);
}
public Condition createSimpleComparisonCondition(String propertyPath, Object value, String comparatorSymbol, boolean ignoreCase) {
return new SimpleComparisonCondition(this, propertyPath, value, comparatorSymbol, ignoreCase);
}
public Condition createLike(String propertyPath, String value, MatchMode matchMode, boolean ignoreCase) {
switch (matchMode) {
case ANYWHERE: value = "%" + value + "%"; break;
case START: value = value + "%"; break;
case END: value = "%" + value; break;
default: throw new IllegalStateException("Unsupported match mode: " + matchMode);
}
return new SimpleComparisonCondition(this, propertyPath, value, "like", ignoreCase);
}
public AndCondition createAnd(Condition... conditions) {
return new AndCondition(this, conditions);
}
public Condition createAnd(List<Condition> conditions) {
return new AndCondition(this, conditions);
}
public OrCondition createOr(Condition... conditions) {
return new OrCondition(this, conditions);
}
public Condition createNot(Condition condition) {
return new NotCondition(this, condition);
}
public Condition createIn(String propertyPath, Collection<?> values) {
return new InCondition(this, propertyPath, values);
}
public Condition createIn(String propertyPath, String subqueryText) {
return new InCondition(this, propertyPath, subqueryText);
}
public Condition createCompareXY(String leftSidePropertyPath, String rightSidePropertyPath, String operator, boolean ignoreCase) {
return new PropertyPropertyComparisonCondition(this, leftSidePropertyPath, rightSidePropertyPath, operator, ignoreCase);
}
}